package com.platform.common.utils.mch;

import com.alibaba.fastjson.JSONObject;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.AESUtil;
import com.platform.common.utils.Md5Utils;
import com.platform.common.utils.StringUtils;
import com.platform.common.utils.ValidUtils;
import com.platform.common.utils.mch.config.MchConfig;

/**
 * 编解码工具
 */
public class CodecUtil {

    /**
     * 数据验证已经解密
     *
     * @param json 入参数据
     * @return 解密后的数据
     */
    public static JSONObject dataDecode(JSONObject json) {
        if (json == null) {
            throw new BusinessException("主体参数为空！");
        }
        String sign = (String) json.remove("sign");
        Long timestampL = (Long) json.remove("timestamp");
        String data = (String) json.remove("data");
        ValidUtils.allNotNull(sign, timestampL);

        // 限制10秒有效
        if (System.currentTimeMillis() - timestampL >= 10000) {
            throw new BusinessException("请求超时");
        }

        // md5 验证
        String md5 = Md5Utils.encryption32(data + timestampL);
        if (!md5.equals(sign)) {
            throw new BusinessException("签名校验失败！");
        }

        // aes 参数解密
        String result = AESUtil.aesDecrypt(data, MchConfig.getKey());
        if (result == null) {
            throw new BusinessException("数据解密失败！");
        }
        return JSONObject.parseObject(result);
    }

    /**
     * 数据加密
     *
     * @param json       待解密数据
     * @param systemCode 系统编码
     * @return 加密后的数据
     */
    public static JSONObject dataEncode(String json, String systemCode) {
        if(StringUtils.isBlank(json)){
            json = "{}";
        }
        // 数据加密
        String encData = AESUtil.aesEncrypt(json, MchConfig.getKey());
        // 构建返回体
        long timestamp = System.currentTimeMillis();
        String sign = Md5Utils.encryption32(encData + systemCode + timestamp);
        JSONObject result = new JSONObject();
        result.put("sign", sign);
        result.put("timestamp", timestamp);
        result.put("data", encData);
        result.put("systemCode", systemCode);
        return result;
    }

}
